import * as Cesium from 'cesium'

const prefix = import.meta.env.VITE_BASE_URL
//距离测量类
export default class MeasureDistance {
  constructor(viewer) {
    this.viewer = viewer
    this.initEvents()
    this.positions = []
    this.tempPositions = []
    this.vertexEntities = new Cesium.EntityCollection()
    this.lineEntity = undefined
    this.isMeasure = false
    this.measureDistance = 0 //测量结果
  }

  //初始化事件
  initEvents() {
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    this.MeasureStartEvent = new Cesium.Event() //开始事件
    this.MeasureEndEvent = new Cesium.Event() //结束事件   
    // 移除默认双击事件trackedEntity
    this.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }

  //激活
  activate() {
    this.deactivate()
    this.registerEvents() //注册鼠标事件  
    //设置鼠标状态 
    this.viewer.enableCursorStyle = false
    this.viewer._element.style.cursor = 'default'
    this.isMeasure = true
    this.measureDistance = 0
  }

  //禁用
  deactivate() {
    if (!this.isMeasure) return
    this.unRegisterEvents()
    this.viewer._element.style.cursor = 'pointer'
    this.viewer.enableCursorStyle = true
    this.isMeasure = false
    this.tempPositions = []
    this.positions = []
    this.vertexEntities.removeAll()
  }

  //清空绘制
  clear() {
    //清除线对象
    this.viewer.entities.remove(this.lineEntity)
    this.lineEntity = undefined

    //清除节点
    this.vertexEntities.values.forEach(item => {
      this.viewer.entities.remove(item)
    })
    this.vertexEntities.removeAll()
  }

  // 计算距离
  computeDistance(points) {
    points = points.map(point => {
      return Cesium.Cartographic.fromCartesian(point)
    })
    // 根据经纬度计算距离
    let start = points[0]
    let end = points[1]
    let geodesic = new Cesium.EllipsoidGeodesic()
    geodesic.setEndPoints(start, end)
    // 计算出两点经纬度之间的距离
    let s = geodesic.surfaceDistance
    // 计算出两点包括高度之间的距离，并将米换算为千米
    s = Math.sqrt(Math.pow(s, 2) + Math.pow(end.height - start.height, 2)) / 1000
    this.measureDistance += s
    return s.toFixed(3)
  }

  //创建线对象
  createLineEntity() {
    this.lineEntity = this.viewer.entities.add({
      polyline: {
        positions: new Cesium.CallbackProperty(e => {
          return this.tempPositions
        }, false),
        width: 2,
        material: Cesium.Color.YELLOW,
        depthFailMaterial: Cesium.Color.YELLOW
      }
    })
  }

  //创建线节点
  createVertex() {
    let vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      id: "MeasureDistanceVertex" + this.positions[this.positions.length - 1],
      type: "MeasureDistanceVertex",
      label: {
        text: this.computeDistance([this.positions.at(-2), this.positions.at(-1)]) + "千米",
        scale: 0.5,
        font: 'normal 24px MicroSoft YaHei',
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        outlineWidth: 9,
        outlineColor: Cesium.Color.RED,
        fillColor: 'red'
      },
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: 8,
        disableDepthTestDistance: 500,
      },
    })
    this.vertexEntities.add(vertexEntity)
  }

  //创建起点
  createStartEntity() {
    let vertexEntity = this.viewer.entities.add({
      position: this.positions[0],
      type: "MeasureDistanceVertex",
      point: {
        color: Cesium.Color.RED,
        pixelSize: 6,
      },
      billboard: {
        image: prefix + "/images/map-marker.png",
        scale: 0.2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      }
    })
    this.vertexEntities.add(vertexEntity)
  }

  //创建终点节点
  createEndEntity() {
    //结束时删除最后一个节点的距离标识
    let lastLabel = this.viewer.entities.getById("MeasureDistanceVertex" + this.positions[this.positions.length - 1])
    this.viewer.entities.remove(lastLabel)
    let vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      type: "MeasureDistanceVertex",
      label: {
        text: "总距离：" + this.measureDistance.toFixed(3) + "千米",
        scale: 0.5,
        font: 'normal 26px MicroSoft YaHei',
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -50),
        outlineWidth: 9,
        outlineColor: Cesium.Color.RED,
        eyeOffset: new Cesium.Cartesian3(0, 0, -10)
      },
      billboard: {
        image: prefix + "/images/map-marker.png",
        scale: 0.2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
      point: {
        color: Cesium.Color.RED,
        pixelSize: 6,
      },
    })
    this.vertexEntities.add(vertexEntity)
  }
  //注册鼠标事件
  registerEvents() {
    this.leftClickEvent()
    this.doubleClickEvent()
    this.mouseMoveEvent()
  }

  //左键点击事件
  leftClickEvent() {
    //单击鼠标左键画点点击事件
    this.handler.setInputAction(e => {
      this.viewer._element.style.cursor = 'default'
      const ellipsoid = this.viewer.scene.globe.ellipsoid
      let position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid)
      if (!position) return
      this.positions.push(position)
      if (this.positions.length == 1) { //首次点击  
        this.createLineEntity()
        this.createStartEntity()
        return
      }
      this.createVertex()

    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  }

  //鼠标移动事件
  mouseMoveEvent() {
    this.handler.setInputAction(e => {
      if (!this.isMeasure) return
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid)
      if (!position) return
      this.handleMoveEvent(position)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  //处理鼠标移动
  handleMoveEvent(position) {
    if (this.positions.length < 1) return
    this.tempPositions = this.positions.concat(position)
  }

  //双击事件
  doubleClickEvent() {
    this.handler.setInputAction(e => {
      this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
      if (!this.isMeasure || this.positions.length < 1) {
        this.deactivate()
        this.clear()
      } else {
        this.createEndEntity()
        this.lineEntity.polyline = {
          positions: this.positions,
          width: 2,
          material: Cesium.Color.YELLOW,
          depthFailMaterial: Cesium.Color.YELLOW
        }
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }

  //测量结束
  measureEnd() {
    this.deactivate()
    this.MeasureEndEvent.raiseEvent(this.measureDistance) //触发结束事件 传入结果
  }

  //解除鼠标事件
  unRegisterEvents() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}